package cn.javacart.jopencart.library.cart;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.javacart.jopencart.library.LanguageService;
import cn.javacart.jopencart.model.Currency;

import com.jfinal.kit.StrKit;

/**
 * 货币服务类，
 * @author farmer
 *
 */
public class CurrencyService {

	private static CurrencyService currencyService = null;
	
	private static Map<String, Currency> currencyMap = new HashMap<String, Currency>();
	
	private CurrencyService(){}
	
	/**
	 * 货币服务类单例
	 * @return
	 */
	public static synchronized CurrencyService getInstance() {
		if (currencyService == null) {
			currencyService = new CurrencyService();
			init();
		}
		return currencyService;
	}

	/**
	 * 初始化
	 */
	private static void init() {
		List<Currency> currencies = Currency.ME.find("select * from joc_currency");
		for (Currency currency : currencies) {
			currencyMap.put(currency.getStr("code"), currency);
		}
	}
	
	/**
	 * 格式化输出金额
	 * @param number
	 * @param currencyCode
	 * @param value
	 * 	汇率
	 * @return
	 */
	public String format(BigDecimal number,String currencyCode ,Float value){
		return format(number, currencyCode, value, true);
	}
	
	/**
	 * 格式化输出金额
	 * @param number
	 * @param currencyCode
	 * @param value
	 * 汇率
	 * @param format
	 * @return
	 */
	public String format(BigDecimal number,String currencyCode , Float value , boolean format){
		Currency currency = currencyMap.get(currencyCode);
		String symbolLeft = currency.getStr("symbol_left");
		String symbolRight = currency.getStr("symbol_right");
		Integer decimalPlace = Integer.parseInt(currency.getStr("decimal_place"));
		if(value == null){
			value = currency.getFloat("value");
		}
		BigDecimal amount = (value != null)?number.multiply(new BigDecimal(value)):number;
		amount.round(new MathContext(decimalPlace, RoundingMode.HALF_UP));	//保留小数
		if(!format){
			return amount.toString();
		}
		StringBuilder formatBuilder = new StringBuilder();
		if(StrKit.notBlank(symbolLeft)){
			formatBuilder.append(symbolLeft);		
		}
		formatBuilder.append(String.format("%"+
							LanguageService.getInstance().getStr("thousand_point")
							+LanguageService.getInstance().getStr("decimal_point")+decimalPlace+"f", amount.doubleValue()));
		if(StrKit.notBlank(symbolRight)){
			formatBuilder.append(symbolRight);
		}
		return formatBuilder.toString();
	}
	
	/**
	 * 价格转换
	 * @param value
	 * @param from
	 * @param to
	 * @return
	 */
	public BigDecimal convert(BigDecimal value ,String from , String to){
		Currency fromCurrency = currencyMap.get(from);
		float fromRate = 1;
		if(fromCurrency != null){
			fromRate = fromCurrency.getFloat("value");
		}
		
		Currency toCurrency = currencyMap.get(to);
		float toRate = 1;
		if(toCurrency != null){
			toRate = toCurrency.getFloat("value");
		}
		return value.multiply(new BigDecimal(toRate).divide(new BigDecimal(fromRate)));
	}
	
	/**
	 * ID
	 * @param code
	 * @return
	 */
	public Integer getId(String code){
		return currencyMap.get(code).getInt("currency_id");
	}
	
	/**
	 * 左边
	 * @param code
	 * @return
	 */
	public String getSymbolLeft(String code) {
		return currencyMap.get(code).getStr("symbol_left");
	}

	/**
	 * 右边
	 * @param code
	 * @return
	 */
	public String getSymbolRight(String code) {
		return currencyMap.get(code).getStr("symbol_right");
	}
	
	/**
	 * 精度
	 * @param code
	 * @return
	 */
	public Integer getDecimalPlace(String code) {
		return Integer.parseInt(currencyMap.get(code).getStr("decimal_place"));
	}
	
	/**
	 * 汇率
	 * @param code
	 * @return
	 */
	public Float getValue(String code){
		return currencyMap.get(code).get("value");
	}
	
	/**
	 * 是否存在该货币
	 * @param code
	 * @return
	 */
	public boolean has(String code) {
		return currencyMap.get(code) != null;
	}
	
}
